package mail

import (
	"fmt"

	"github.com/emersion/go-imap"
	"github.com/emersion/go-imap/client"
)

type IMailboxMsgCb interface {
	MessageUpdateCb(*imap.Message)
	ExppungeCb(*client.ExpungeUpdate)
	MailboxUpdateCb(imap.StatusItem, *imap.MailboxStatus)
	StatusUpdateCb(imap.StatusRespType, *client.StatusUpdate)
}

type listenData struct {
	value    interface{}
	dataType client.Update
}

func (mc *MailClient) cbListening() {
	msgCb := mc.GetMailboxMsgCb()
	if msgCb == nil {
		fmt.Printf("mailbox message callback handle isn't implemented\n")
	}
	go func() {
		defer RecoverPanic(func(err interface{}) {
			mc.cbListening()
		})
		for data := range mc.GetTriggerCbCh() {
			if data == nil || InterfaceIsNil(msgCb) {
				continue
			}
			copyData := *data
			wrapper(msgCb, copyData.dataType, &copyData)
		}
	}()
}

func wrapper(msgCb IMailboxMsgCb, t client.Update, copyData *listenData) {
	go func() {
		defer RecoverPanic()
		switch d := t.(type) {
		case *client.ExpungeUpdate:
			msgCb.ExppungeCb(d)
		case *client.MessageUpdate:
			msgCb.MessageUpdateCb(d.Message)
		case *client.StatusUpdate:
			msgCb.StatusUpdateCb(d.Status.Type, d)
		case *client.MailboxUpdate:
			msgCb.MailboxUpdateCb(copyData.value.(imap.StatusItem), d.Mailbox)

		}
	}()
}
